6章 トランザクション
6.1 トランザクションの構造
トランザクションメッセージの構造はRLPエンコーディングスキームを使用してシリアライズされる https://miro.medium.com/max/2480/1*IxHl8-O1EYt48FpKQB_Sww.png
6.2 トランザクションナンス
ナンス(nonce)はトランザクションにおいて最も重要で、最も理解されていない要素の一つ
シナリオ1
6 ether重要な支払いをしようとして、加えて8 ether払う場合を考える
6 etherのほうが重要なので、最初に署名してブロードキャストする
次に8 etherに署名してブロードキャストする
自分のアカウントに10 etherしかなかった!
両方のトランザクションを受け入れることはできない。片方は失敗する
最初に重要な6 etherを送ったから、8 etherのトランザクションが拒否されると思うかもしれない
しかし、分散システムではノードはどちらの順序でトランザクションを受け取るかは決まっていない!
ナンスがないとどちらが先に受け入れられるかはランダムになる
ナンスが含まれていれば、例えば最初のトランザクションはナンス3、次のトランザクションはナンス4とする
先にナンス4のトランザクションが受け取られても、0~3のナンスのトランザクションが処理されるまでは、待つ
シナリオ2
オンライン上で商品を買う
AさんはBさんに2 ether送る
Bさんは商品を送る
同じアドレスに2 ether送信するトランザクションナンスが無いと同じに見える
何回もトランザクションを「再生」することができてしまう
トランザクションにナンス値がある場合、毎回のトランザクションは別のものと認識される
ナンスを持つことで支払いの複製ができなくなる
ビットコインプロトコルのUTXO(Unspent Transaction Output)メカニズムとは対照的 ナンスの仕組みはアカウントベース (account-based)のプロトコルにとって必要不可欠
6.2.1 ナンスの追跡
ナンスはアカウントから発行された承認済み(confirmed)、オンチェーンのトランザクションの最新カウント数
web3インターフェースを通してブロックチェーンに問い合わせると分かる
MetaMaskを実行しているブラウザのコンソールかtruffle consoleコマンドでアクセスしてみよう
callbackが必要ぽい。
code:example.js
web3.eth.getTransactionCount("自分が管理しているアドレスをここに入れる", function(error, result){
if(!error)
console.log(JSON.stringify(result));
else
console.error(error);
})
ネットワークのチェック
code:network-check.js
web3.version.getNetwork((err, netId) => {
switch (netId) {
case "1":
console.log('This is mainnet')
break
case "2":
console.log('This is the deprecated Morden test network.')
break
case "3":
console.log('This is the ropsten test network.')
break
case "4":
console.log('This is the Rinkeby test network.')
break
case "42":
console.log('This is the Kovan test network.')
break
default:
console.log('This is an unknown network.')
}
})
6.3 トランザクションガス
メインネットのガス価格とかわかる
ガスはイーサリアムの"燃料"
トランザクションが使用できるリソース料を制御するためにガスを使用する
ガスはイーサから分離されている
イーサの価値の急激な変動からシステムを保護するため
gasPriceが高いほどトランザクションは早く承認される可能性が高くなる
web3インターフェースのgasPriceはいくつかのブロックに渡って含まれたトランザクションのガス価格の中央値を計算
code:gasprice.js
web3.eth.getGasPrice(console.log)
6.4 トランザクション受信者
トランザクション受信者は toフィールドで指定される
20バイトのイーサリアムアドレスを含む
焼却(burning)
対応する秘密鍵またはコントラクトがないアドレスに送信するとイーサは焼却され使用できなくなる
6.5 トランザクションのバリューとデータ
トランザクションの主なペイロードはvalueとdataの2つのフィールドに含まれている
トランザクションはバリューとデータ、バリューのみ、データのみ、両方持たない、4つの組み合わせが有効
バリューのあるトランザクションは支払い(payment)トランザクション
データのみのトランザクションは呼び出し(invocation) トランザクション
両方無いトランザクションは可能だけどガスの無駄
成金っぽい june29.icon
バリューをEOAとコントラクトに送信する
イーサリアムは状態の変更を記録、アドレスの残高に送信したバリューを追加
toがコントラクトの場合、EVMはコントラクトを実行し、トランザクションのデータペイロードに指定された関数の呼び出しを試みる
トランザクションにデータがない場合はEVMはfallback関数を呼び出す。その関数が支払い可能な場合はフォールバック関数を実行して、次の処理を決定する
トランザクションにデータが含まれている場合は、ほとんどはコントラクトアドレス宛
EOAにデータペイロードを送信できるけど、データの解釈はウォレット次第
EOAによるデータペイロードの解釈はコントラクト実行とは異なり、コンセンサスルールの対象とはならない
データはEVMによってコントラクトの呼び出しとして解釈される
データを関数の呼び出しとして使用し、名前付き関数を呼び出し、その関数にエンコードされた引数を渡す
ABI互換のコントラクトに送信されるデータペイロードは以下の16進法のエンコード code:payload.js
web3.sha3("withdraw(uint256)");
// => "0x2e1a7d4d13322e7b96f9a57413e1525c250fb7a9021cf91d1540d5b69f16a49f" Keccak-256ハッシュ
withdraw_amount = web3.toWei(0.01, "ether");
// => "10000000000000000"
withdraw_amount_hex = web3.toHex(withdraw_amount);
// => "0x2386f26fc10000"
6.6 特別なトランザクション: コントラクト作成
特別なケース
将来に備えてそれをデプロイするトランザクションがある
年金っぽい june29.icon
コントラクト作成トランザクションはゼロアドレスと呼ばれる特殊なアドレスに送信される
toフィールドには0x0が含まれる。このアドレスはEOAもコントラクトアドレスも表していない
コントラクト作成を目的としているけど、支払いを受け取ることがある
コントラクト作成のためにゼロアドレスを宛先とする場合でも常にtoパラメータを指定するのがおすすめ
誤って0x0に送信して、永久に失うコストが大きすぎるから
6.7 デジタル署名
イーサリアムで使用されるデジタル署名アルゴリズムは ECDSA 楕円曲線デジタルアルゴリズム
シンプルリプレイアタックプロテクション
6.8 署名プレフィックス値(v)と公開鍵リカバリ
トランザクションメッセージにはfromは含まれていない
トランザクション発行者の公開鍵はECDSA署名から直接計算できる
署名者の公開鍵を回復するプロセスは公開鍵リカバリ
rとsが与えられた場合、2つの取りうる可能性のある公開鍵が計算できる
6.9 署名と送信の分離(オフライン署名)
トランザクションが署名されると、イーサリアムネットワークに送信する準備が整う
web3.eth.sendTransaction
トランザクション作成、署名、ブロードキャスト
なぜ署名と送信を分離したいか -> 安全性
署名と送信の機能を別々に分けて実行することは、オフライン署名と呼ばれる
セキュリティの方法としては一般的
6.10 トランザクションの伝播
イーサリアムネットワークは「フラッドルーティング」プロトコルを使用
充満(flooding)
起点を追跡したり、伝播を邪魔するには攻撃者はノードのうちの割合を支配する必要がある
6.11 ブロックチェーンへのレコーディング
マイナー(miner)
マイニングファーム(mining farm)
6.12 複数署名(マルチシグ)トランザクション
ビットコインのスクリプティング機能
ビットコインマルチシグアカウント
複数の当事者がトランザクションに署名する場合のみ資金を使用できる
HUNTERxHUNTER のボマーだ june29.icon
イーサリアムのマルチシグネチャトランザクション
余分な柔軟性が安全性を損なうバグに繋がる可能性
6.13 まとめ
トランザクションは全体としてはイーサリアムブロックチェーン全体の状態を変更するための「インプット」
hr.icon
次章!